/*
* Copyright (C) 2012-2014 qar
* License: http://www.gnu.org/licenses/gpl.html GPL version 2
*/

#include "crypto/counter.h"

#include "util.h"

Counter::Counter(qint64 size) {
    ASSERT(size % 8 == 0);
    words.resize(size / 8);
    init();
}

Counter::~Counter()
{}

QByteArray Counter::data() const {
    QByteArray result;
    QDataStream out(&result, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_0);
    foreach (quint64 w, words) {
        out << w;
    }
    return result;
}

void Counter::init(QByteArray data) {
    QDataStream in(&data, QIODevice::ReadOnly);
    in.setVersion(QDataStream::Qt_4_0);
    for (int i = 0; i < words.count(); i++) {
        words[i] = 0;
        in >> words[i];
    }
}

void Counter::init() {
    qint64 time = currentNanoSecsSinceEpoch();
    QByteArray result;
    QDataStream out(&result, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_0);
    out << time;
    init(result);
}

QByteArray Counter::increment()
{
    for (int i = words.count() - 1; i >= 0; i--) {
        quint64 old = words[i];
        words[i]++;
        if (words[i] > old) {
            // No overflow
            break;
        }
    }
    return data();
}
